package com.feixiang.springbootinit.processor;
import cn.hutool.core.date.DateUtil;
import cn.hutool.json.JSONUtil;
import com.feixiang.springbootinit.common.ErrorCode;
import com.feixiang.springbootinit.constant.WxConstant;
import com.feixiang.springbootinit.exception.BusinessException;
import com.feixiang.springbootinit.model.entity.wechat.ChatData;
import com.feixiang.springbootinit.model.entity.wechat.QwMessage;
import com.feixiang.springbootinit.model.enums.SessionArchiveMsgActionEnum;
import com.feixiang.springbootinit.model.enums.SessionArchiveMsgTypeEnum;
import com.feixiang.springbootinit.model.vo.wechat.MsgVO;
import com.feixiang.springbootinit.service.QwMessageService;
import com.feixiang.springbootinit.strategy.MessageProcessingStrategy;
import com.feixiang.springbootinit.strategy.MessageStrategyFactory;
import com.feixiang.springbootinit.utils.SessionArchiveUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.security.PrivateKey;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;
@Slf4j
//@Component
@Deprecated
/**
 * 单线程处理
 *
 */
public class SessionArchiveProcessorSingle {

    @Autowired
    private QwMessageService messageService;

    @Autowired
    private MessageStrategyFactory messageStrategyFactory;

    public List<QwMessage> processMessages(List<ChatData> chatdataList) {
        // 1. 初始化线程池
        ExecutorService executor = Executors.newFixedThreadPool(10);
        List<Future<QwMessage>> futures = new ArrayList<>();
        // 2. 获取解密私钥（主线程中只需做一次）
        PrivateKey privateKey = SessionArchiveUtil.getPrivateKey(WxConstant.PRIVKEY);
        if (privateKey == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "企微解密私钥为空");
        }
        // 3. 提交所有处理任务
        for (ChatData chatData : chatdataList) {
            futures.add(executor.submit(() -> {
                // 每个线程需要独立初始化SDK
                Long sdk = null;
                try {
                    sdk = SessionArchiveUtil.initSDK(WxConstant.CORP_ID, WxConstant.SECRET_KEY);
                    return processSingleMessage(chatData, privateKey);
                } finally {
                    // 确保SDK释放
                    if (sdk != null) {
                        // 销毁SDK
                        SessionArchiveUtil.destroy();
                    }
                }
            }));
        }
        // 4. 收集结果
        List<QwMessage> result = new ArrayList<>();
        for (Future<QwMessage> future : futures) {
            try {
                QwMessage message = future.get(30, TimeUnit.SECONDS); // 设置超时时间
                if (message != null) {
                    result.add(message);
                }
            } catch (TimeoutException e) {
                log.error("消息处理超时", e);
            } catch (Exception e) {
                log.error("处理消息异常", e);
            }
        }

        // 5. 关闭线程池
        executor.shutdown();
        try {
            if (!executor.awaitTermination(60, TimeUnit.SECONDS)) {
                executor.shutdownNow();
            }
        } catch (InterruptedException e) {
            executor.shutdownNow();
            Thread.currentThread().interrupt();
        }

        return result;
    }

    private QwMessage processSingleMessage(ChatData chatData, PrivateKey privateKey) {
        // 这里不需要再处理SDK，因为已经在任务提交时处理了
        try {
            String randomKey = SessionArchiveUtil.decrptyRandomKey(privateKey, chatData.getEncryptRandomKey());
            //获取解密后的消息内容Json格式
            String decryptMsg = SessionArchiveUtil.decryptData(SessionArchiveUtil.getSDK(), randomKey, chatData.getEncryptChatMsg());
            MsgVO msgVO = JSONUtil.toBean(decryptMsg, MsgVO.class);
            QwMessage message = buildBaseMessage(chatData, msgVO,decryptMsg);
            //基础消息信息入库
            messageService.save(message);
            //根据消息类型分发消息类型处理策略,文本消息就取解密内容中的content即可，图片,文件等需处理。
            MessageProcessingStrategy processor = messageStrategyFactory.getStrategy(SessionArchiveMsgTypeEnum.fromString(msgVO.getMsgtype()));
            if (processor != null) {
                //处理消息
                processor.process(msgVO, message);
            }
            return message;
        } catch (Exception e) {
            log.error("处理消息失败, seq: {}", chatData.getSeq(), e);
            return null;
        }
    }
    /**
     * 构建基础消息对象
     *
     * @param chatData   企业微信原始加密数据，包含seq等元信息
     * @param msgVO      解密后的消息内容对象，包含消息类型、发送者等业务字段
     * @param decryptMsg 解密后的原始消息内容(JSON字符串)，用于完整存储
     * @return 业务系统的Message实体，根据action类型初始化不同字段：
     *         - SWITCH: 企业切换日志，存储完整解密消息，msgtype固定为"switch"
     *         - SEND:   普通发送消息，包含发送者、接收列表等完整信息
     *         - RECALL: 消息撤回记录，结构与SEND一致
     */
    private QwMessage buildBaseMessage(ChatData chatData, MsgVO msgVO, String decryptMsg) {
        // 1. 参数校验
        if (StringUtils.isAnyBlank(chatData.getSeq().toString(), msgVO.getMsgid(), msgVO.getAction(), decryptMsg)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "参数缺失: chatData.seq, msgVO.msgid, msgVO.action, decryptMsg 不能为空");
        }
        // 2. 初始化基础对象
        QwMessage message = new QwMessage();
        message.setSeq(chatData.getSeq());
        message.setMsgId(msgVO.getMsgid());
        message.setAction(msgVO.getAction());
        message.setContent(decryptMsg);
        // 3. 根据action类型处理不同分支
        String action = msgVO.getAction();
        if (SessionArchiveMsgActionEnum.SWITCH.getCode().equals(action)) {
            handleSwitchMessage(message, msgVO);
        } else if (SessionArchiveMsgActionEnum.SEND.getCode().equals(action)) {
            handleSendMessage(message, msgVO);
        } else if (SessionArchiveMsgActionEnum.RECALL.getCode().equals(action)) {
            handleSendMessage(message, msgVO); // RECALL和SEND处理逻辑相同
        } else {
            log.warn("未知的action类型: {}", action);
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "非法的action类型: " + action);
        }

        return message;
    }

    // 处理切换企业日志
    private void handleSwitchMessage(QwMessage message, MsgVO msgVO) {
        message.setMsgtime(DateUtil.date(msgVO.getTime()));
        message.setMsgtype(SessionArchiveMsgActionEnum.SWITCH.getCode());
        log.debug("构建企业切换消息: msgId={}", msgVO.getMsgid());
    }

    // 处理发送/撤回消息(SEND和RECALL共用)
    private void handleSendMessage(QwMessage message, MsgVO msgVO) {
        message.setFromId(msgVO.getFrom());
        message.setMsgtype(msgVO.getMsgtype());
        message.setTolist(JSONUtil.toJsonStr(msgVO.getTolist()));
        message.setRoomid(msgVO.getRoomid());
        Date msgTime = DateUtil.date(msgVO.getMsgtime());
        message.setMsgtime(msgTime);
        message.setCreatedTime(new Date());
        log.debug("构建{}消息: msgId={}, 发送时间={}",
                message.getAction(), message.getMsgId(), msgTime);
    }
}